<?php
/**
 * PsiFramework
 *
 * Php Simple Framework
 *
 * PHP version 5.3
 *
 * @category  PsiFramework.Plugins.CMS.Classes.Actions
 * @package   PsiFramework.Plugins.CMS.Classes.Actions
 * @author    Remi San <remi.san@gmail.com>
 * @copyright 2011 Remi San
 * @license   http://creativecommons.org/licenses/by/3.0/  Creative Commons CC BY 3.0
 * @version   SVN: <svn_id>
 * @link      http://www.psiframework.com/phpdoc/classes/db_\PsiFramework\Plugins.CMS.Classes.Actions.SaveAction.html
 */

namespace PsiFramework\Plugins\CMS\Classes\Actions;

import("Classes.Actions.AbstractAction");
import("Classes.Factory.DAOFactory");
import("Classes.Factory.ObjectFactory");
import("Classes.Util.Database.Database");
import("Classes.Util.Manager.ApplicationManager");
import("Classes.Util.Object.Date");

use \PsiFramework\Classes\Actions\AbstractAction;
use \PsiFramework\Classes\Factory\DAOFactory;
use \PsiFramework\Classes\Factory\ObjectFactory;
use \PsiFramework\Classes\Util\Database\Database;
use \PsiFramework\Classes\Util\Manager\ApplicationManager;
use \PsiFramework\Classes\Util\Object\Date;
use \PsiFramework\Classes\Util\Object\File;
use \PsiFramework\Classes\Util\Object\Image;

/**
 * Default save action
 * 
 * This is the default class for the save action.
 *
 * @category PsiFramework.Plugins.CMS.Classes.Actions
 * @package  PsiFramework.Plugins.CMS.Classes.Actions
 * @author   Remi San <remi.san@gmail.com>
 * @license  http://creativecommons.org/licenses/by/3.0/  Creative Commons CC BY 3.0
 * @link     http://www.psiframework.com/phpdoc/classes/db_\PsiFramework\Plugins.CMS.Classes.Actions.SaveAction.html
 */
class SaveAction extends AbstractAction
{
    /**
     * Counts the parts described in the form
     * 
     * @param string $prefix The prefix of the parts
     * 
     * @return int
     */
    protected function countParts($prefix)
    {
        $partIds = $this->_request->getParameter($prefix.'part_id', false);
        return count($partIds);
    }

    /**
     * Retrieve the parts described in the form
     * 
     * @param array  $saveObject   Save object paramaters
     * @param array  $linkObject   Link object parameters
     * @param array  $linkedObject Linked object parameters 
     * @param array  $options      The options
     * @param string $prefix       The prefix of the parts
     * @param bool   $manageDates  Dates to manage ?
     * 
     * @return array
     */
    protected function getParts(
        /*array*/  $saveObject,
        /*array*/  $linkObject,
        /*array*/  $linkedObject,
        /*array*/  $options,
        /*string*/ $prefix='',
        /*bool*/   $manageDates=true
    )
    {
        $now = Date::now();
        if (!isNullOrEmptyString($prefix)) {
            $prefix .= '_' ;
        } else {
            $prefix = '' ;
        }

        $partIds = $this->_request->getParameter($prefix.'part_id', false);
        $deleteIds = $this->_request->getParameter($prefix.'delete', false);

        $objectDao = DAOFactory::getDAO($linkedObject['name']);
        $partDao = DAOFactory::getDAO($linkObject['name']);

        if (!is_null($deleteIds)) {
            foreach ($deleteIds as $objectId) {
                if (!isNullOrEmptyString($objectId)) {
                    $object = $objectDao->retrieveByPk($objectId);
                    if (!is_null($objectId)) {
                        $part = ObjectFactory::getNewObject(
                            $linkObject['name']
                        );
                        $part->{$saveObject['setter']}($saveObject['value']);
                        $part->{$linkedObject['setter']}($object);
                        $partDao->delete($part, false);
                    }
                }
            }
        }

        $parameters = array();
        foreach ($options as $option) {
            $parameters[$option['name']]
                = $this->_request->getParameter($prefix.$option['name'], false);
        }

        $parts = array();
        if (!is_null($partIds)) {
            for ($i=0; $i<count($partIds); $i++) {
                $objectId = $partIds[$i] ;
                if (!isNullOrEmptyString($objectId)) {
                    $object = $objectDao->retrieveByPk($objectId);
                    if (!is_null($objectId)) {
                        $part = ObjectFactory::getNewObject(
                            $linkObject['name']
                        );
                        $part->{$saveObject['setter']}($saveObject['value']);
                        $part->{$linkedObject['setter']}($object);

                        $retrievedPart = $partDao->retrieveByPk($part->getId());
                        if (is_null($retrievedPart)) {
                            if ($manageDates) {
                                $part->setCreationDate($now);
                            }
                        } else {
                            $part = $retrievedPart ;
                        }

                        foreach ($options as $option) {
                            $part->{$option['setter']}(
                                $parameters[$option['name']][$i]
                            );
                        }
                        
                        if ($manageDates) {
                            $part->setModificationDate($now);
                        }
                        
                        $partDao->save($part, false);
                        $parts[] = $part ;
                    }
                }
            }
        }

        return $parts ;
    }

    protected function getImage(
        /*string*/ $varName,
        /*string*/ $path,
        /*int*/    $width=null,
        /*int*/    $height=null,
        /*Image*/  $oldImage=null
    )
    {
        $image = $this->_request->getFile($varName);
        if (is_null($image)) {
        	$delete = $this->_request->getParameter('delete_'.$varName);
        	$imagePath = $this->_request->getParameter('current_'.$varName);
        	if (isNullOrEmptyString($delete)) {
        		$image = $imagePath;
        	} else {
        		if (file_exists($imagePath)) {
        	        @unlink($imagePath);
        		}
        	}
        }
        
        if ($image instanceof File) {
        	$fileName = uniqid().'.'.$image->getExtension();
        	$filePath = realpath($path);
        	$image->setName($fileName);
        	$image->moveTo($filePath);
            
        	if (!isNullOrEmptyString($width) && !isNullOrEmptyString($height)) {
            	$newPath = $filePath.'/resized_'.$fileName;
            	$newImage = new Image($image);
            	$newImage->createResizedPictures(
        			$newPath,
        			$width,
        			$height
            	);
            
            	$file = new File();
            	$file->unserialize($newPath);
            	$image = new Image($file);
        	}
        	
        	if (!isNullOrEmptyString($oldImage)) {
        	    unlink($oldImage->getFileLink());
        	}
        } else if (!isNullOrEmptyString($image)) {
        	$file = new File();
        	$file->unserialize($image);
        	$image = new Image($file);
        } else {
        	$image = null;
        }
        
        return $image;
    }

    /**
     * The main function of the method which is called every time
     * an action is created by the front controller.
     * 
     * @see    AbstractAction::execute()
     * @return void
     */
    public function execute()
    {
        parent::execute();

        $database = Database::getInstance();
        $database->startTransaction();

        try {
            $obj = null ;
            $dao = DAOFactory::getDAO($this->_objectType);
            if ($this->_id != null) {
                $obj = $dao->retrieveByPk($this->_id);
            }

            if ($obj == null) {
                $obj = ObjectFactory::getNewObject($this->_objectType);
            }

            $functionName = 'get'.$this->_objectType ;
            $obj = $this->$functionName($dao, $obj);
            if (!is_null($obj)) {
                $dao->save($obj, false);
            }

            $database->commit();
        }catch(\Exception $e) {
            $database->rollback();
            throw $e ;
        }

        $objectParameters
            = ApplicationManager::getInstance()->
                                  getApplication()->getObjectParameter(
                                      $this->_objectType
                                  );

        $this->_response->setAttribute("object", $obj);
        $this->_response->setAttribute(
            "columns",
            $objectParameters->getParameters()
        );
        $this->findForward('success');
    }
}
